package com.starlink.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.convert.Convert;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageHelper;
import com.starlink.common.exception.BusinessException;
import com.starlink.context.SessionContext;
import com.starlink.mapper.MallIntegrationMapper;
import com.starlink.model.domain.*;
import com.starlink.model.dtomapper.MallPeripherySpecificationDtoMapper;
import com.starlink.model.request.MallPeripheryDetailRequest;
import com.starlink.model.request.MallPeripherySpecificationRequest;
import com.starlink.model.request.save.MallBooksSpecificationSaveRequest;
import com.starlink.model.request.save.MallPeripherySaveRequest;
import com.starlink.model.util.MallPeripheryConvert;
import com.starlink.model.vo.MallBooksVO;
import com.starlink.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.Pageable;
import com.starlink.common.utils.AssertUtil;
import com.starlink.model.dtomapper.MallPeripheryDtoMapper;
import com.starlink.mapper.MallPeripheryMapper;
import com.starlink.model.request.MallPeripheryRequest;
import com.starlink.model.vo.MallPeripheryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.starlink.utils.IDUtils.getId;
import static com.starlink.utils.PageUtils.getOrderBy;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 */
@Service
public class MallPeripheryServiceImpl extends ServiceImpl<MallPeripheryMapper, MallPeripheryDO> implements MallPeripheryService {
    @Autowired
    private MallPeripheryMapper mallPeripheryMapper;
    @Autowired
    private MallPeripherySpecificationService specificationService;
    @Autowired
    private MallPeripheryDetailService provisionerService;
    @Autowired
    private MallIntegrationMapper mallIntegrationMapper;
    @Autowired
    private ShoppingCartOrderDetailsService cartOrderDetailsService;
    @Autowired
    private MallPeripheryOrderDetailsService peripheryOrderDetailsService;
    @Autowired
    private MallIntegrationOrderService integrationOrderService;

    @Override
    public MallPeripheryVO getByKey(long id) {
        MallPeripherySaveRequest request = new MallPeripherySaveRequest();
        request.setId(id);
        request.setUserId(SessionContext.getWechatUserId());
        List<MallPeripheryVO> list = mallPeripheryMapper.getByKey(request);
        return list.get(0);
    }

    @Override
    public PageInfo<List<MallPeripheryVO>> pageQuery(Pageable pageable,MallPeripherySaveRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), getOrderBy(pageable.getSort())).setReasonable(true);
        List<MallPeripheryVO> list = mallPeripheryMapper.pagingQuery(request);
        return new PageInfo(list);
    }

    @Override
    public List<MallPeripheryVO> listQuery(MallPeripheryRequest request) {
        List<MallPeripheryDO> list = mallPeripheryMapper.selectDOList(MallPeripheryDtoMapper.INSTANCE.request2DO(request));
        List<MallPeripheryVO> mallPeripheryVOS = MallPeripheryConvert.buildMallPeripheryVoList(list);
        return mallPeripheryVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long add(MallPeripheryRequest request) {
        request.setId(getId());
        MallPeripheryDO request2DO = MallPeripheryDtoMapper.INSTANCE.request2DO(request);
        mallPeripheryMapper.insertDO(request2DO);
        return request2DO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(MallPeripheryRequest request) {
        AssertUtil.assertNotNull(request.getId(), "id不能为空");
        saveOrUpdate(MallPeripheryDtoMapper.INSTANCE.request2DO(request));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteDOByIds(String ids) {
        Long id = Long.valueOf(ids);
        List<Long> idList = mallIntegrationMapper.selectDOByArticlesId(id);
        if (CollectionUtils.isNotEmpty(idList)){
            List<MallIntegrationOrderDO> integrationOrderDOS = integrationOrderService.lambdaQuery().in(MallIntegrationOrderDO::getMallIntegrationId, idList).list();
            if (CollectionUtils.isNotEmpty(integrationOrderDOS)){
                throw new BusinessException("该书籍已存在积分订单,暂不能删除");
            }
        }
        List<ShoppingCartOrderDetailsDO> cartOrderDetailsDOList = cartOrderDetailsService.lambdaQuery().eq(ShoppingCartOrderDetailsDO::getArticlesId, id).list();
        List<MallPeripheryOrderDetailsDO> peripheryOrderDetailsDOS = peripheryOrderDetailsService.lambdaQuery().eq(MallPeripheryOrderDetailsDO::getMallPeripheryId, id).list();

        if (CollectionUtils.isNotEmpty(peripheryOrderDetailsDOS) || CollectionUtils.isNotEmpty(cartOrderDetailsDOList)){
            throw new BusinessException("该商品已存在订单,暂不能删除");
        }
        if (CollectionUtils.isNotEmpty(idList)){
            throw new BusinessException("该商品已被积分商城关联,暂不能删除");
        }
        mallPeripheryMapper.deleteDOByIds(Convert.toStrArray(ids));
        specificationService.deletedByPerIds(ids);
        provisionerService.deletedByPerIds(ids);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertOrUpdateDO(MallPeripherySaveRequest request) {
        List<MallPeripherySpecificationRequest> specification = request.getSpecification();
        MallPeripheryRequest peripheryRequest = new MallPeripheryRequest();
        peripheryRequest.setFreeTemplateId(request.getFreeTemplateId());
        peripheryRequest.setName(request.getName());
        peripheryRequest.setPicture(request.getPicture());
        peripheryRequest.setSortOrder(request.getSortOrder());
        if (request.getId()==null) {
            peripheryRequest.setOnTheShelf(0);
            peripheryRequest.setCreateUser(SessionContext.getAdminUserId());
            peripheryRequest.setCreateTime(new Date());
            Long perId = this.add(peripheryRequest);
            if (CollectionUtils.isNotEmpty(specification)){
                List<MallPeripherySpecificationDO> specificationDOS = specification.stream().map(item -> {
                    item.setMallPeripheryId(perId);
                    item.setId(getId());
                    MallPeripherySpecificationDO specificationDO = MallPeripherySpecificationDtoMapper.INSTANCE.request2DO(item);
                    return specificationDO;
                }).collect(Collectors.toList());
                specificationService.saveBatch(specificationDOS);
            }
            MallPeripheryDetailRequest detailRequest = new MallPeripheryDetailRequest();
            detailRequest.setPeripheryInfo(request.getPeripheryInfo());
            detailRequest.setMallPeripheryId(perId);
            detailRequest.setId(getId());
            provisionerService.add(detailRequest);
        }else {
            peripheryRequest.setUpdateUser(SessionContext.getAdminUserId());
            peripheryRequest.setUpdateTime(new Date());
            Long perId = request.getId();
            peripheryRequest.setId(perId);
            this.updateByKey(peripheryRequest);
            if (CollectionUtils.isNotEmpty(specification)){
                List<Long> speIdList = specification.stream().map(MallPeripherySpecificationRequest::getId).collect(Collectors.toList());
                List<MallPeripherySpecificationDO> specificationDOS = specificationService.lambdaQuery().eq(MallPeripherySpecificationDO::getMallPeripheryId, perId).list();
                if (CollectionUtils.isNotEmpty(specificationDOS)){
                    List<Long> list = new ArrayList<>();
                    List<Long> longs = specificationDOS.stream().map(MallPeripherySpecificationDO::getId).collect(Collectors.toList());
                    longs.forEach(id->{
                        if (!speIdList.contains(id)){
                            list.add(id);
                        }
                    });
                    if (CollectionUtils.isNotEmpty(list)){
                        List<MallPeripheryOrderDetailsDO> perOrderList = peripheryOrderDetailsService.lambdaQuery().in(MallPeripheryOrderDetailsDO::getSpecificationId, list).list();
                        List<ShoppingCartOrderDetailsDO> cartOrderDetailsDOList = cartOrderDetailsService.lambdaQuery().in(ShoppingCartOrderDetailsDO::getSpecificationId, list).list();
                        if (CollectionUtils.isNotEmpty(perOrderList) || CollectionUtils.isNotEmpty(cartOrderDetailsDOList)){
                            throw new BusinessException("您删除的规格存在订单关联,暂不能删除");
                        }
                    }
                }
                specificationService.deletedByPerId(perId);
                specification.forEach(item -> {
                    item.setMallPeripheryId(perId);
                    specificationService.add(item);
                });
            }
            provisionerService.updateByPerId(request.getPeripheryInfo(),request.getId());
        }
        return true;
    }

    @Override
    public PageInfo<List<MallPeripheryVO>> pageList(Pageable pageable, MallPeripherySaveRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), getOrderBy(pageable.getSort())).setReasonable(true);
        List<MallPeripheryVO> mallPeripheryVOS = mallPeripheryMapper.pageList(request);
        return new PageInfo(mallPeripheryVOS);
    }
}
